]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
st: Switch to render nodes
authorGeorges Basile Stavracas Neto <georges.stavracas@gmail.com>
Thu, 10 Dec 2020 20:21:11 +0000 (17:21 -0300)
committerJonas Ådahl <jadahl@gmail.com>
Tue, 18 Jun 2024 14:59:38 +0000 (16:59 +0200)
Switch to render nodes. Most of the changes follow the pattern of
replacing a cogl_framebuffer_draw_*() call by (1) creating a paint
node, and (2) calling the corresponding clutter_paint_node_add_*()
API.

StWidget now overrides ClutterActor.paint_node(), instead of paint.
All subclasses that overrided the paint vfunc also are changed to
override paint_node.

The entry point for CSS rendering, st_widget_paint_background(), now
receives a root ClutterPaintNode, and propagates it to the rendering
machinery.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1538>

16 files changed:
src/st/st-entry.c
src/st/st-icon.c
src/st/st-label.c
src/st/st-private.c
src/st/st-private.h
src/st/st-shadow.c
src/st/st-shadow.h
src/st/st-theme-node-drawing.c
src/st/st-theme-node-private.h
src/st/st-theme-node-transition.c
src/st/st-theme-node-transition.h
src/st/st-theme-node.c
src/st/st-theme-node.h
src/st/st-viewport.c
src/st/st-widget.c
src/st/st-widget.h

index d90d4da6b46fb5f4ad84d4b8331348e3edee1b38..ccd6e3f9a9c099f225671d22396b7b7ba4ae6fa1 100644 (file)
@@ -817,13 +817,12 @@ st_entry_leave_event (ClutterActor *actor,
 }
 
 static void
-st_entry_paint (ClutterActor        *actor,
-                ClutterPaintContext *paint_context)
+st_entry_paint_node (ClutterActor     *actor,
+                     ClutterPaintNode *node)
 {
   StEntryPrivate *priv = ST_ENTRY_PRIV (actor);
-  ClutterActorClass *parent_class;
 
-  st_widget_paint_background (ST_WIDGET (actor), paint_context);
+  st_widget_paint_background (ST_WIDGET (actor), node);
 
   if (priv->shadow_spec)
     {
@@ -851,23 +850,13 @@ st_entry_paint (ClutterActor        *actor,
 
       if (priv->text_shadow_material != NULL)
         {
-          CoglFramebuffer *framebuffer =
-            clutter_paint_context_get_framebuffer (paint_context);
-
           _st_paint_shadow_with_opacity (priv->shadow_spec,
-                                         framebuffer,
+                                         node,
                                          priv->text_shadow_material,
                                          &allocation,
                                          clutter_actor_get_paint_opacity (priv->entry));
         }
     }
-
-  /* Since we paint the background ourselves, chain to the parent class
-   * of StWidget, to avoid painting it twice.
-   * This is needed as we still want to paint children.
-   */
-  parent_class = g_type_class_peek_parent (st_entry_parent_class);
-  parent_class->paint (actor, paint_context);
 }
 
 static void
@@ -901,7 +890,7 @@ st_entry_class_init (StEntryClass *klass)
   actor_class->get_preferred_width = st_entry_get_preferred_width;
   actor_class->get_preferred_height = st_entry_get_preferred_height;
   actor_class->allocate = st_entry_allocate;
-  actor_class->paint = st_entry_paint;
+  actor_class->paint_node = st_entry_paint_node;
   actor_class->unmap = st_entry_unmap;
   actor_class->get_paint_volume = st_entry_get_paint_volume;
 
index 122999893ebf0b3b5a76a680d5c411292afe423a..c02ab493cd36639efe2faba410a5a8429fd3a7e6 100644 (file)
@@ -200,13 +200,13 @@ st_icon_dispose (GObject *gobject)
 }
 
 static void
-st_icon_paint (ClutterActor        *actor,
-               ClutterPaintContext *paint_context)
+st_icon_paint_node (ClutterActor     *actor,
+                    ClutterPaintNode *node)
 {
   StIcon *icon = ST_ICON (actor);
   StIconPrivate *priv = icon->priv;
 
-  st_widget_paint_background (ST_WIDGET (actor), paint_context);
+  st_widget_paint_background (ST_WIDGET (actor), node);
 
   if (priv->icon_texture)
     {
@@ -215,18 +215,14 @@ st_icon_paint (ClutterActor        *actor,
       if (priv->shadow_pipeline)
         {
           ClutterActorBox allocation;
-          CoglFramebuffer *framebuffer;
 
           clutter_actor_get_allocation_box (priv->icon_texture, &allocation);
-          framebuffer = clutter_paint_context_get_framebuffer (paint_context);
           _st_paint_shadow_with_opacity (priv->shadow_spec,
-                                         framebuffer,
+                                         node,
                                          priv->shadow_pipeline,
                                          &allocation,
                                          clutter_actor_get_paint_opacity (priv->icon_texture));
         }
-
-      clutter_actor_paint (priv->icon_texture, paint_context);
     }
 }
 
@@ -300,7 +296,7 @@ st_icon_class_init (StIconClass *klass)
   object_class->set_property = st_icon_set_property;
   object_class->dispose = st_icon_dispose;
 
-  actor_class->paint = st_icon_paint;
+  actor_class->paint_node = st_icon_paint_node;
 
   widget_class->style_changed = st_icon_style_changed;
   actor_class->resource_scale_changed = st_icon_resource_scale_changed;
index 71cadb58d0e199ceacd2db52810d9ee9b6d16853..d53dc588f45237fedcd75651b2aa1afe3d8ff89f 100644 (file)
@@ -205,12 +205,12 @@ st_label_dispose (GObject   *object)
 }
 
 static void
-st_label_paint (ClutterActor        *actor,
-                ClutterPaintContext *paint_context)
+st_label_paint_node (ClutterActor     *actor,
+                     ClutterPaintNode *node)
 {
   StLabelPrivate *priv = ST_LABEL (actor)->priv;
 
-  st_widget_paint_background (ST_WIDGET (actor), paint_context);
+  st_widget_paint_background (ST_WIDGET (actor), node);
 
   if (priv->shadow_spec)
     {
@@ -241,19 +241,13 @@ st_label_paint (ClutterActor        *actor,
 
       if (priv->text_shadow_pipeline != NULL)
         {
-          CoglFramebuffer *framebuffer;
-
-          framebuffer =
-            clutter_paint_context_get_framebuffer (paint_context);
           _st_paint_shadow_with_opacity (priv->shadow_spec,
-                                         framebuffer,
+                                         node,
                                          priv->text_shadow_pipeline,
                                          &allocation,
                                          clutter_actor_get_paint_opacity (priv->label));
         }
     }
-
-  clutter_actor_paint (priv->label, paint_context);
 }
 
 static void
@@ -278,7 +272,7 @@ st_label_class_init (StLabelClass *klass)
   gobject_class->get_property = st_label_get_property;
   gobject_class->dispose = st_label_dispose;
 
-  actor_class->paint = st_label_paint;
+  actor_class->paint_node = st_label_paint_node;
   actor_class->allocate = st_label_allocate;
   actor_class->get_preferred_width = st_label_get_preferred_width;
   actor_class->get_preferred_height = st_label_get_preferred_height;
index 38b2c9c5c61b45cf1c69b8465c77d35cf742cbb9..5caabcd07b4eeec6e80d8b2b240ac9d3ce8098e1 100644 (file)
@@ -773,12 +773,13 @@ _st_create_shadow_cairo_pattern (StShadow        *shadow_spec_in,
 }
 
 void
-_st_paint_shadow_with_opacity (StShadow        *shadow_spec,
-                               CoglFramebuffer *framebuffer,
-                               CoglPipeline    *shadow_pipeline,
-                               ClutterActorBox *box,
-                               guint8           paint_opacity)
+_st_paint_shadow_with_opacity (StShadow         *shadow_spec,
+                               ClutterPaintNode *node,
+                               CoglPipeline     *shadow_pipeline,
+                               ClutterActorBox  *box,
+                               guint8            paint_opacity)
 {
+  g_autoptr (ClutterPaintNode) pipeline_node = NULL;
   ClutterActorBox shadow_box;
   CoglColor color;
 
@@ -794,8 +795,8 @@ _st_paint_shadow_with_opacity (StShadow        *shadow_spec,
                            shadow_spec->color.alpha / 255.0 * paint_opacity / 255.0);
   cogl_color_premultiply (&color);
   cogl_pipeline_set_layer_combine_constant (shadow_pipeline, 0, &color);
-  cogl_framebuffer_draw_rectangle (framebuffer,
-                                   shadow_pipeline,
-                                   shadow_box.x1, shadow_box.y1,
-                                   shadow_box.x2, shadow_box.y2);
+
+  pipeline_node = clutter_pipeline_node_new (shadow_pipeline);
+  clutter_paint_node_add_child (node, pipeline_node);
+  clutter_paint_node_add_rectangle (pipeline_node, &shadow_box);
 }
index 3f1fd12957923ff37c1255460fd0cfe467964cba..6e5c1197ac4e37a6430ba788bd68adf6440aa75e 100644 (file)
@@ -66,10 +66,10 @@ CoglPipeline * _st_create_shadow_pipeline_from_actor (StShadow     *shadow_spec,
 cairo_pattern_t *_st_create_shadow_cairo_pattern (StShadow        *shadow_spec,
                                                   cairo_pattern_t *src_pattern);
 
-void _st_paint_shadow_with_opacity (StShadow        *shadow_spec,
-                                    CoglFramebuffer *framebuffer,
-                                    CoglPipeline    *shadow_pipeline,
-                                    ClutterActorBox *box,
-                                    guint8           paint_opacity);
+void _st_paint_shadow_with_opacity (StShadow         *shadow_spec,
+                                    ClutterPaintNode *node,
+                                    CoglPipeline     *shadow_pipeline,
+                                    ClutterActorBox  *box,
+                                    guint8            paint_opacity);
 
 #endif /* __ST_PRIVATE_H__ */
index 7239241b4174aba8ebdebfe386763c38e9a20c01..a406b61532f33641141bb93d99ff595511ac06d4 100644 (file)
@@ -281,7 +281,7 @@ st_shadow_helper_free (StShadowHelper *helper)
 /**
  * st_shadow_helper_paint:
  * @helper: a #StShadowHelper
- * @framebuffer: a #CoglFramebuffer
+ * @node: a #ClutterPaintNode
  * @actor_box: the bounding box of the shadow
  * @paint_opacity: the opacity at which the shadow is painted
  *
@@ -289,13 +289,13 @@ st_shadow_helper_free (StShadowHelper *helper)
  * be called from the implementation of ClutterActor::paint().
  */
 void
-st_shadow_helper_paint (StShadowHelper  *helper,
-                        CoglFramebuffer *framebuffer,
-                        ClutterActorBox *actor_box,
-                        guint8           paint_opacity)
+st_shadow_helper_paint (StShadowHelper   *helper,
+                        ClutterPaintNode *node,
+                        ClutterActorBox  *actor_box,
+                        uint8_t           paint_opacity)
 {
   _st_paint_shadow_with_opacity (helper->shadow,
-                                 framebuffer,
+                                 node,
                                  helper->pipeline,
                                  actor_box,
                                  paint_opacity);
index b24ab9b04bf7c1e1e66c2d4ac48c7d5d352a902c..f7703f9433c2c8f5e933b8c628303a841e07fb95 100644 (file)
@@ -84,10 +84,10 @@ void            st_shadow_helper_free (StShadowHelper *helper);
 void            st_shadow_helper_update (StShadowHelper *helper,
                                          ClutterActor   *source);
 
-void            st_shadow_helper_paint (StShadowHelper  *helper,
-                                        CoglFramebuffer *framebuffer,
-                                        ClutterActorBox *actor_box,
-                                        guint8           paint_opacity);
+void            st_shadow_helper_paint (StShadowHelper   *helper,
+                                        ClutterPaintNode *node,
+                                        ClutterActorBox  *actor_box,
+                                        uint8_t           paint_opacity);
 
 G_END_DECLS
 
index b938558d15fbc03f10eedaa293d760a743fd5481..774544cc0e05c45f5937d6e64248bd258107161c 100644 (file)
@@ -1363,7 +1363,7 @@ st_theme_node_prerender_background (StThemeNode *node,
 }
 
 static void st_theme_node_paint_borders (StThemeNodePaintState *state,
-                                         CoglFramebuffer       *framebuffer,
+                                         ClutterPaintNode      *node,
                                          const ClutterActorBox *box,
                                          StPaintBordersMode     mode,
                                          guint8                 paint_opacity);
@@ -1667,12 +1667,13 @@ st_theme_node_update_resources (StThemeNodePaintState *state,
 }
 
 static void
-paint_material_with_opacity (CoglPipeline    *material,
-                             CoglFramebuffer *framebuffer,
-                             ClutterActorBox *box,
-                             ClutterActorBox *coords,
-                             guint8           paint_opacity)
+paint_material_with_opacity (ClutterPaintNode *node,
+                             CoglPipeline     *material,
+                             ClutterActorBox  *box,
+                             ClutterActorBox  *coords,
+                             guint8            paint_opacity)
 {
+  g_autoptr (ClutterPaintNode) pipeline_node = NULL;
   CoglColor color;
 
   cogl_color_init_from_4f (&color,
@@ -1680,37 +1681,20 @@ paint_material_with_opacity (CoglPipeline    *material,
                            paint_opacity / 255.0, paint_opacity / 255.0);
   cogl_pipeline_set_color (material, &color);
 
+  pipeline_node = clutter_pipeline_node_new (material);
+  clutter_paint_node_add_child (node, pipeline_node);
+
   if (coords)
-    cogl_framebuffer_draw_textured_rectangle (framebuffer, material,
-                                              box->x1, box->y1, box->x2, box->y2,
-                                              coords->x1, coords->y1, coords->x2, coords->y2);
+    clutter_paint_node_add_texture_rectangle (pipeline_node, box,
+                                              coords->x1, coords->y1,
+                                              coords->x2, coords->y2);
   else
-    cogl_framebuffer_draw_rectangle (framebuffer, material,
-                                     box->x1, box->y1, box->x2, box->y2);
-}
-
-static void
-st_theme_node_ensure_color_pipeline (StThemeNode *node)
-{
-  static CoglPipeline *color_pipeline_template = NULL;
-
-  if (node->color_pipeline != NULL)
-    return;
-
-  if (G_UNLIKELY (color_pipeline_template == NULL))
-    {
-      CoglContext *ctx =
-        clutter_backend_get_cogl_context (clutter_get_default_backend ());
-
-      color_pipeline_template = cogl_pipeline_new (ctx);
-    }
-
-  node->color_pipeline = cogl_pipeline_copy (color_pipeline_template);
+    clutter_paint_node_add_rectangle (pipeline_node, box);
 }
 
 static void
 st_theme_node_paint_borders (StThemeNodePaintState *state,
-                             CoglFramebuffer       *framebuffer,
+                             ClutterPaintNode      *root,
                              const ClutterActorBox *box,
                              StPaintBordersMode     mode,
                              guint8                 paint_opacity)
@@ -1766,13 +1750,14 @@ st_theme_node_paint_borders (StThemeNodePaintState *state,
 
       if (alpha > 0)
         {
-          st_theme_node_ensure_color_pipeline (node);
-          cogl_color_init_from_4f (&pipeline_color,
-                                   effective_border.red / 255.0 * alpha / 255.0,
-                                   effective_border.green / 255.0 * alpha / 255.0,
-                                   effective_border.blue / 255.0 * alpha / 255.0,
-                                   alpha / 255.0);
-          cogl_pipeline_set_color (node->color_pipeline, &pipeline_color);
+          g_autoptr (ClutterPaintNode) border_color_node = NULL;
+          CoglColor color;
+
+          cogl_color_init_from_4f (&color,
+                                   effective_border.red / 255.0f,
+                                   effective_border.green / 255.0f,
+                                   effective_border.blue / 255.0f,
+                                   alpha / 255.0f);
 
           /* NORTH */
           skip_corner_1 = border_radius[ST_CORNER_TOPLEFT] > 0;
@@ -1815,9 +1800,11 @@ st_theme_node_paint_borders (StThemeNodePaintState *state,
           rects[15] = skip_corner_2 ? height - max_width_radius[ST_CORNER_BOTTOMLEFT]
                              : height - border_width[ST_SIDE_BOTTOM];
 
-          cogl_framebuffer_draw_rectangles (framebuffer,
-                                            node->color_pipeline,
-                                           rects, 4);
+          border_color_node = clutter_color_node_new (&color);
+          clutter_paint_node_set_static_name (border_color_node,
+                                              "StThemeNode (CSS borders)");
+          clutter_paint_node_add_child (root, border_color_node);
+          clutter_paint_node_add_rectangles (border_color_node, rects, 4);
         }
     }
 
@@ -1833,44 +1820,67 @@ st_theme_node_paint_borders (StThemeNodePaintState *state,
     {
       for (corner_id = 0; corner_id < 4; corner_id++)
         {
+          g_autoptr (ClutterPaintNode) corners_node = NULL;
+
           if (state->corner_material[corner_id] == NULL)
             continue;
 
           cogl_pipeline_set_color (state->corner_material[corner_id], &pipeline_color);
 
+          corners_node =
+            clutter_pipeline_node_new (state->corner_material[corner_id]);
+          clutter_paint_node_set_static_name (corners_node,
+                                              "StThemeNode (CSS border corners)");
+          clutter_paint_node_add_child (root, corners_node);
+
           switch (corner_id)
             {
-              case ST_CORNER_TOPLEFT:
-                cogl_framebuffer_draw_textured_rectangle (framebuffer,
-                  state->corner_material[corner_id], 0, 0,
-                  max_width_radius[ST_CORNER_TOPLEFT], max_width_radius[ST_CORNER_TOPLEFT],
-                  0, 0, 0.5, 0.5);
-                break;
-              case ST_CORNER_TOPRIGHT:
-                cogl_framebuffer_draw_textured_rectangle (framebuffer,
-                  state->corner_material[corner_id],
-                  width - max_width_radius[ST_CORNER_TOPRIGHT], 0,
-                  width, max_width_radius[ST_CORNER_TOPRIGHT],
-                  0.5, 0, 1, 0.5);
-                break;
-              case ST_CORNER_BOTTOMRIGHT:
-                cogl_framebuffer_draw_textured_rectangle (framebuffer,
-                  state->corner_material[corner_id],
-                  width - max_width_radius[ST_CORNER_BOTTOMRIGHT],
-                  height - max_width_radius[ST_CORNER_BOTTOMRIGHT],
-                  width, height,
-                  0.5, 0.5, 1, 1);
-                break;
-              case ST_CORNER_BOTTOMLEFT:
-                cogl_framebuffer_draw_textured_rectangle (framebuffer,
-                  state->corner_material[corner_id],
-                  0, height - max_width_radius[ST_CORNER_BOTTOMLEFT],
-                  max_width_radius[ST_CORNER_BOTTOMLEFT], height,
-                  0, 0.5, 0.5, 1);
-                break;
-              default:
-                g_assert_not_reached();
-                break;
+            case ST_CORNER_TOPLEFT:
+              clutter_paint_node_add_texture_rectangle (corners_node,
+                                                        &(ClutterActorBox) {
+                                                          0, 0,
+                                                          max_width_radius[ST_CORNER_TOPLEFT],
+                                                          max_width_radius[ST_CORNER_TOPLEFT],
+                                                        },
+                                                        0.0, 0.0,
+                                                        0.5, 0.5);
+              break;
+            case ST_CORNER_TOPRIGHT:
+              clutter_paint_node_add_texture_rectangle (corners_node,
+                                                        &(ClutterActorBox) {
+                                                          width - max_width_radius[ST_CORNER_TOPRIGHT],
+                                                          0,
+                                                          width,
+                                                          max_width_radius[ST_CORNER_TOPRIGHT],
+                                                        },
+                                                        0.5, 0.0,
+                                                        1.0, 0.5);
+              break;
+            case ST_CORNER_BOTTOMRIGHT:
+              clutter_paint_node_add_texture_rectangle (corners_node,
+                                                        &(ClutterActorBox) {
+                                                          width - max_width_radius[ST_CORNER_BOTTOMRIGHT],
+                                                          height - max_width_radius[ST_CORNER_BOTTOMRIGHT],
+                                                          width,
+                                                          height,
+                                                        },
+                                                        0.5, 0.5,
+                                                        1.0, 1.0);
+              break;
+            case ST_CORNER_BOTTOMLEFT:
+              clutter_paint_node_add_texture_rectangle (corners_node,
+                                                        &(ClutterActorBox) {
+                                                          0,
+                                                          height - max_width_radius[ST_CORNER_BOTTOMLEFT],
+                                                          max_width_radius[ST_CORNER_BOTTOMLEFT],
+                                                          height,
+                                                        },
+                                                        0.0, 0.5,
+                                                        0.5, 1.0);
+              break;
+            default:
+              g_assert_not_reached();
+              break;
             }
         }
     }
@@ -1881,13 +1891,20 @@ st_theme_node_paint_borders (StThemeNodePaintState *state,
           paint_opacity * node->background_color.alpha / 255;
   if (alpha > 0)
     {
-      st_theme_node_ensure_color_pipeline (node);
-      cogl_color_init_from_4f (&pipeline_color,
-                               node->background_color.red / 255.0 * alpha / 255.0,
-                               node->background_color.green / 255.0 * alpha / 255.0,
-                               node->background_color.blue / 255.0 * alpha / 255.0,
-                               alpha / 255.0);
-      cogl_pipeline_set_color (node->color_pipeline, &pipeline_color);
+      g_autoptr (ClutterPaintNode) background_color_node = NULL;
+      CoglColor color;
+
+      cogl_color_init_from_4f (&color,
+                               node->background_color.red / 255.0f,
+                               node->background_color.green / 255.0f,
+                               node->background_color.blue / 255.0f,
+                               alpha / 255.0f);
+
+      background_color_node = clutter_color_node_new (&color);
+      clutter_paint_node_set_static_name (background_color_node,
+                                          "StThemeNode (CSS background color)");
+      clutter_paint_node_add_child (root, background_color_node);
+
       /* We add padding to each corner, so that all corners end up as if they
        * had a border-radius of max_border_radius, which allows us to treat
        * corners as uniform further on.
@@ -1973,9 +1990,10 @@ st_theme_node_paint_borders (StThemeNodePaintState *state,
                 g_assert_not_reached();
                 break;
             }
-          cogl_framebuffer_draw_rectangles (framebuffer,
-                                            node->color_pipeline,
-                                            verts, n_rects);
+
+          clutter_paint_node_add_rectangles (background_color_node,
+                                             verts,
+                                             n_rects);
         }
 
       /* Once we've drawn the borders and corners, if the corners are bigger
@@ -1990,32 +2008,44 @@ st_theme_node_paint_borders (StThemeNodePaintState *state,
        * necessary, then the main rectangle
        */
       if (max_border_radius > border_width[ST_SIDE_TOP])
-        cogl_framebuffer_draw_rectangle (framebuffer, node->color_pipeline,
-                                         MAX(max_border_radius, border_width[ST_SIDE_LEFT]),
-                                         border_width[ST_SIDE_TOP],
-                                         width - MAX(max_border_radius, border_width[ST_SIDE_RIGHT]),
-                                         max_border_radius);
+        {
+          clutter_paint_node_add_rectangle (background_color_node,
+                                            &(ClutterActorBox) {
+                                              MAX (max_border_radius, border_width[ST_SIDE_LEFT]),
+                                              border_width[ST_SIDE_TOP],
+                                              width - MAX (max_border_radius, border_width[ST_SIDE_RIGHT]),
+                                              max_border_radius,
+                                            });
+        }
+
       if (max_border_radius > border_width[ST_SIDE_BOTTOM])
-        cogl_framebuffer_draw_rectangle (framebuffer, node->color_pipeline,
-                                         MAX(max_border_radius, border_width[ST_SIDE_LEFT]),
-                                         height - max_border_radius,
-                                         width - MAX(max_border_radius, border_width[ST_SIDE_RIGHT]),
-                                         height - border_width[ST_SIDE_BOTTOM]);
-
-      cogl_framebuffer_draw_rectangle (framebuffer, node->color_pipeline,
-                                       border_width[ST_SIDE_LEFT],
-                                       MAX(border_width[ST_SIDE_TOP], max_border_radius),
-                                       width - border_width[ST_SIDE_RIGHT],
-                                       height - MAX(border_width[ST_SIDE_BOTTOM], max_border_radius));
+        {
+          clutter_paint_node_add_rectangle (background_color_node,
+                                            &(ClutterActorBox) {
+                                              MAX (max_border_radius, border_width[ST_SIDE_LEFT]),
+                                              height - max_border_radius,
+                                              width - MAX (max_border_radius, border_width[ST_SIDE_RIGHT]),
+                                              height - border_width[ST_SIDE_BOTTOM],
+                                            });
+        }
+
+      clutter_paint_node_add_rectangle (background_color_node,
+                                        &(ClutterActorBox) {
+                                          border_width[ST_SIDE_LEFT],
+                                          MAX (border_width[ST_SIDE_TOP], max_border_radius),
+                                          width - border_width[ST_SIDE_RIGHT],
+                                          height - MAX (border_width[ST_SIDE_BOTTOM], max_border_radius)
+                                        });
     }
 }
 
 static void
 st_theme_node_paint_sliced_shadow (StThemeNodePaintState *state,
-                                   CoglFramebuffer       *framebuffer,
+                                   ClutterPaintNode      *root,
                                    const ClutterActorBox *box,
                                    guint8                 paint_opacity)
 {
+  g_autoptr (ClutterPaintNode) pipeline_node = NULL;
   StThemeNode *node = state->node;
   guint border_radius[4];
   CoglColor color;
@@ -2261,50 +2291,118 @@ st_theme_node_paint_sliced_shadow (StThemeNodePaintState *state,
         }
     }
 
-  cogl_framebuffer_draw_textured_rectangles (framebuffer, state->box_shadow_pipeline,
-                                             rectangles, idx / 8);
+  pipeline_node = clutter_pipeline_node_new (state->box_shadow_pipeline);
+  clutter_paint_node_set_static_name (pipeline_node,
+                                      "StThemeNode (CSS box-shadow)");
+  clutter_paint_node_add_child (root, pipeline_node);
+  clutter_paint_node_add_texture_rectangles (pipeline_node,
+                                             rectangles,
+                                             idx / 8);
 
 #if 0
+  g_autoptr (ClutterPaintNode) color_node = NULL;
+  CoglColor red;
+
   /* Visual feedback on shadow's 9-slice and original offscreen buffer,
      for debug purposes */
-  cogl_framebuffer_draw_rectangle (framebuffer, state->box_shadow_pipeline,
-                                   xend, yoffset, xend + shadow_width, yoffset + shadow_height);
-
-  st_theme_node_ensure_color_pipeline (node);
-  cogl_color_init_from_4f (&color, 1.0, 0.0, 0.0, 1.0);
-  cogl_pipeline_set_color (node->color_pipeline, &color);
-
-  cogl_framebuffer_draw_rectangle (framebuffer, node->color_pipeline,
-                                   xoffset, top, xend, top + 1);
-  cogl_framebuffer_draw_rectangle (framebuffer, node->color_pipeline,
-                                   xoffset, bottom, xend, bottom + 1);
-  cogl_framebuffer_draw_rectangle (framebuffer, node->color_pipeline,
-                                   left, yoffset, left + 1, yend);
-  cogl_framebuffer_draw_rectangle (framebuffer, node->color_pipeline,
-                                   right, yoffset, right + 1, yend);
-
-  cogl_framebuffer_draw_rectangle (framebuffer, node->color_pipeline,
-                                   xend, yoffset, xend + shadow_width, yoffset + 1);
-  cogl_framebuffer_draw_rectangle (framebuffer, node->color_pipeline,
-                                   xend, yoffset + shadow_height, xend + shadow_width, yoffset + shadow_height + 1);
-  cogl_framebuffer_draw_rectangle (framebuffer, node->color_pipeline,
-                                   xend, yoffset, xend + 1, yoffset + shadow_height);
-  cogl_framebuffer_draw_rectangle (framebuffer, node->color_pipeline,
-                                   xend + shadow_width, yoffset, xend + shadow_width + 1, yoffset + shadow_height);
+  clutter_paint_node_add_rectangle (pipeline_node,
+                                    &(ClutterActorBox) {
+                                      xend,
+                                      yoffset,
+                                      xend + shadow_width,
+                                      yoffset + shadow_height,
+                                    });
+
+  cogl_color_init_from_4f (&red, 1.0, 0.0, 0.0, 1.0);
+  cogl_pipeline_set_color (node->color_pipeline, &red);
+  color_node = clutter_color_node_new (&red);
+  clutter_paint_node_set_static_name (color_node,
+                                      "StThemeNode (CSS box-shadow - debug)");
+  clutter_paint_node_add_child (root, color_node);
+
+  clutter_paint_node_add_rectangle (color_node,
+                                    &(ClutterActorBox) {
+                                      xoffset,
+                                      top,
+                                      xend,
+                                      top + 1,
+                                    });
+  clutter_paint_node_add_rectangle (color_node,
+                                    &(ClutterActorBox) {
+                                      xoffset,
+                                      bottom,
+                                      xend,
+                                      bottom + 1,
+                                    });
+  clutter_paint_node_add_rectangle (color_node,
+                                    &(ClutterActorBox) {
+                                      left,
+                                      yoffset,
+                                      left + 1,
+                                      yend,
+                                    });
+  clutter_paint_node_add_rectangle (color_node,
+                                    &(ClutterActorBox) {
+                                      right,
+                                      yoffset,
+                                      right + 1,
+                                      yend,
+                                    });
+
+  clutter_paint_node_add_rectangle (color_node,
+                                    &(ClutterActorBox) {
+                                      xend,
+                                      yoffset,
+                                      xend + shadow_width,
+                                      yoffset + 1,
+                                    });
+  clutter_paint_node_add_rectangle (color_node,
+                                    &(ClutterActorBox) {
+                                      xend,
+                                      yoffset + shadow_height,
+                                      xend + shadow_width,
+                                      yoffset + shadow_height + 1,
+                                    });
+  clutter_paint_node_add_rectangle (color_node,
+                                    &(ClutterActorBox) {
+                                      xend,
+                                      yoffset,
+                                      xend + 1,
+                                      yoffset + shadow_height,
+                                    });
+  clutter_paint_node_add_rectangle (color_node,
+                                    &(ClutterActorBox) {
+                                      xend + shadow_width,
+                                      yoffset,
+                                      xend + shadow_width + 1,
+                                      yoffset + shadow_height,
+                                    });
 
   s_top *= shadow_height;
   s_bottom *= shadow_height;
   s_left *= shadow_width;
   s_right *= shadow_width;
 
-  cogl_framebuffer_draw_rectangle (framebuffer, node->color_pipeline,
-                                   xend, yoffset + s_top, xend + shadow_width, yoffset + s_top + 1);
-  cogl_framebuffer_draw_rectangle (framebuffer, node->color_pipeline,
-                                   xend, yoffset + s_bottom, xend + shadow_width, yoffset + s_bottom + 1);
-  cogl_framebuffer_draw_rectangle (framebuffer, node->color_pipeline,
-                                   xend + s_left, yoffset, xend + s_left + 1, yoffset + shadow_height);
-  cogl_framebuffer_draw_rectangle (framebuffer, node->color_pipeline,
-                                   xend + s_right, yoffset, xend + s_right + 1, yoffset + shadow_height);
+  clutter_paint_node_add_rectangle (color_node,
+                                    &(ClutterActorBox) {
+                                      xend, yoffset + s_top,
+                                      xend + shadow_width, yoffset + s_top + 1,
+                                    });
+  clutter_paint_node_add_rectangle (color_node,
+                                    &(ClutterActorBox) {
+                                      xend, yoffset + s_bottom,
+                                      xend + shadow_width, yoffset + s_bottom + 1,
+                                    });
+  clutter_paint_node_add_rectangle (color_node,
+                                    &(ClutterActorBox) {
+                                      xend + s_left, yoffset,
+                                      xend + s_left + 1, yoffset + shadow_height,
+                                    });
+  clutter_paint_node_add_rectangle (color_node,
+                                    &(ClutterActorBox) {
+                                      xend + s_right, yoffset,
+                                      xend + s_right + 1, yoffset + shadow_height,
+                                    });
 
 #endif
 }
@@ -2334,6 +2432,9 @@ st_theme_node_prerender_shadow (StThemeNodePaintState *state)
 
   if (cogl_framebuffer_allocate (framebuffer, &error))
     {
+      g_autoptr (ClutterPaintNode) root_node = NULL;
+      ClutterPaintContext *paint_context;
+      CoglColor clear_color;
       ClutterActorBox box = { 0, 0, state->box_shadow_width, state->box_shadow_height};
 
       cogl_framebuffer_orthographic (framebuffer, 0, 0,
@@ -2341,9 +2442,21 @@ st_theme_node_prerender_shadow (StThemeNodePaintState *state)
       cogl_framebuffer_scale (framebuffer,
                               state->resource_scale,
                               state->resource_scale, 1);
-      cogl_framebuffer_clear4f (framebuffer, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 0);
 
-      st_theme_node_paint_borders (state, framebuffer, &box, ST_PAINT_BORDERS_MODE_SILHOUETTE, 0xFF);
+      cogl_color_init_from_4f (&clear_color, 0, 0, 0, 0);
+      root_node = clutter_root_node_new (framebuffer,
+                                         &clear_color,
+                                         COGL_BUFFER_BIT_COLOR);
+
+      st_theme_node_paint_borders (state, root_node, &box,
+                                   ST_PAINT_BORDERS_MODE_SILHOUETTE, 0xff);
+
+      paint_context =
+        clutter_paint_context_new_for_framebuffer (framebuffer,
+                                                   NULL,
+                                                   CLUTTER_PAINT_FLAG_NONE);
+      clutter_paint_node_paint (root_node, paint_context);
+      clutter_paint_context_destroy (paint_context);
 
       state->box_shadow_pipeline = _st_create_shadow_pipeline (st_theme_node_get_box_shadow (node),
                                                                buffer, state->resource_scale);
@@ -2388,12 +2501,13 @@ st_theme_node_compute_maximum_borders (StThemeNodePaintState *state)
 }
 
 static void
-st_theme_node_paint_sliced_border_image (StThemeNode           *node,
-                                         CoglFramebuffer       *framebuffer,
-                                         float                  width,
-                                         float                  height,
-                                         guint8                 paint_opacity)
+st_theme_node_paint_sliced_border_image (StThemeNode      *node,
+                                         ClutterPaintNode *root,
+                                         float             width,
+                                         float             height,
+                                         guint8            paint_opacity)
 {
+  g_autoptr (ClutterPaintNode) pipeline_node = NULL;
   gfloat ex, ey;
   gfloat tx1, ty1, tx2, ty2;
   gint border_left, border_right, border_top, border_bottom;
@@ -2479,21 +2593,27 @@ st_theme_node_paint_sliced_border_image (StThemeNode           *node,
       1.0, 1.0
     };
 
-    cogl_framebuffer_draw_textured_rectangles (framebuffer, pipeline, rectangles, 9);
+    pipeline_node = clutter_pipeline_node_new (pipeline);
+    clutter_paint_node_set_static_name (pipeline_node,
+                                        "StThemeNode (CSS border image)");
+    clutter_paint_node_add_child (root, pipeline_node);
+    clutter_paint_node_add_texture_rectangles (pipeline_node, rectangles, 9);
   }
 }
 
 static void
 st_theme_node_paint_outline (StThemeNode           *node,
-                             CoglFramebuffer       *framebuffer,
+                             ClutterPaintNode      *root,
                              const ClutterActorBox *box,
                              guint8                 paint_opacity)
 
 {
+  g_autoptr (ClutterPaintNode) outline_node = NULL;
+  CoglColor color;
   float width, height;
   int outline_width;
   float rects[16];
-  CoglColor outline_color, effective_outline, pipeline_color;
+  CoglColor outline_color, effective_outline;
   guint8 alpha;
 
   width = box->x2 - box->x1;
@@ -2508,13 +2628,11 @@ st_theme_node_paint_outline (StThemeNode           *node,
 
   alpha = paint_opacity * outline_color.alpha / 255;
 
-  st_theme_node_ensure_color_pipeline (node);
-  cogl_color_init_from_4f (&pipeline_color,
-                           effective_outline.red / 255.0 * alpha / 255.0,
-                           effective_outline.green / 255.0 * alpha / 255.0,
-                           effective_outline.blue / 255.0 * alpha / 255.0,
-                           alpha / 255.0);
-  cogl_pipeline_set_color (node->color_pipeline, &pipeline_color);
+  cogl_color_init_from_4f (&color,
+                           effective_outline.red / 255.0f,
+                           effective_outline.green / 255.0f,
+                           effective_outline.blue / 255.0f,
+                           alpha / 255.0f);
 
   /* The outline is drawn just outside the border, which means just
    * outside the allocation box. This means that in some situations
@@ -2546,7 +2664,11 @@ st_theme_node_paint_outline (StThemeNode           *node,
   rects[14] = 0;
   rects[15] = height;
 
-  cogl_framebuffer_draw_rectangles (framebuffer, node->color_pipeline, rects, 4);
+  outline_node = clutter_color_node_new (&color);
+  clutter_paint_node_set_static_name (outline_node,
+                                      "StThemeNode (CSS outline)");
+  clutter_paint_node_add_child (root, outline_node);
+  clutter_paint_node_add_rectangles (outline_node, rects, 4);
 }
 
 static gboolean
@@ -2594,7 +2716,7 @@ st_theme_node_needs_new_box_shadow_for_size (StThemeNodePaintState *state,
 void
 st_theme_node_paint (StThemeNode           *node,
                      StThemeNodePaintState *state,
-                     CoglFramebuffer       *framebuffer,
+                     ClutterPaintNode      *root,
                      const ClutterActorBox *box,
                      guint8                 paint_opacity,
                      float                  resource_scale)
@@ -2669,13 +2791,13 @@ st_theme_node_paint (StThemeNode           *node,
       if (state->alloc_width < node->box_shadow_min_width ||
           state->alloc_height < node->box_shadow_min_height)
         _st_paint_shadow_with_opacity (node->box_shadow,
-                                       framebuffer,
+                                       root,
                                        state->box_shadow_pipeline,
                                        &allocation,
                                        paint_opacity);
       else
         st_theme_node_paint_sliced_shadow (state,
-                                           framebuffer,
+                                           root,
                                            &allocation,
                                            paint_opacity);
     }
@@ -2691,22 +2813,22 @@ st_theme_node_paint (StThemeNode           *node,
                                                   &allocation,
                                                   &paint_box);
 
-          paint_material_with_opacity (state->prerendered_pipeline,
-                                       framebuffer,
+          paint_material_with_opacity (root,
+                                       state->prerendered_pipeline,
                                        &paint_box,
                                        NULL,
                                        paint_opacity);
         }
 
       if (node->border_slices_pipeline != NULL)
-        st_theme_node_paint_sliced_border_image (node, framebuffer, width, height, paint_opacity);
+        st_theme_node_paint_sliced_border_image (node, root, width, height, paint_opacity);
     }
   else
     {
-      st_theme_node_paint_borders (state, framebuffer, box, ST_PAINT_BORDERS_MODE_COLOR, paint_opacity);
+      st_theme_node_paint_borders (state, root, box, ST_PAINT_BORDERS_MODE_COLOR, paint_opacity);
     }
 
-  st_theme_node_paint_outline (node, framebuffer, box, paint_opacity);
+  st_theme_node_paint_outline (node, root, box, paint_opacity);
 
   if (state->prerendered_pipeline == NULL &&
       st_theme_node_load_background_image (node, resource_scale))
@@ -2725,9 +2847,15 @@ st_theme_node_paint (StThemeNode           *node,
                                &background_box, &texture_coords);
 
       if (has_visible_outline || node->background_repeat)
-        cogl_framebuffer_push_rectangle_clip (framebuffer,
-                                              allocation.x1, allocation.y1,
-                                              allocation.x2, allocation.y2);
+        {
+          g_autoptr (ClutterPaintNode) clip_node = NULL;
+
+          clip_node = clutter_clip_node_new ();
+          clutter_paint_node_add_child (root, clip_node);
+          clutter_paint_node_add_rectangle (clip_node, &allocation);
+
+          root = clip_node;
+        }
 
       /* CSS based drop shadows
        *
@@ -2744,19 +2872,16 @@ st_theme_node_paint (StThemeNode           *node,
        */
       if (node->background_shadow_pipeline != NULL)
         _st_paint_shadow_with_opacity (node->background_image_shadow,
-                                       framebuffer,
+                                       root,
                                        node->background_shadow_pipeline,
                                        &background_box,
                                        paint_opacity);
 
-      paint_material_with_opacity (node->background_pipeline,
-                                   framebuffer,
+      paint_material_with_opacity (root,
+                                   node->background_pipeline,
                                    &background_box,
                                    &texture_coords,
                                    paint_opacity);
-
-      if (has_visible_outline || node->background_repeat)
-        cogl_framebuffer_pop_clip (framebuffer);
     }
 }
 
index 82ca8876394f7f056b73dad1a493dfdfc5242e31..9a910089cd61850a6fb19f903cd0b30aa05e81c3 100644 (file)
@@ -112,7 +112,6 @@ struct _StThemeNode {
   CoglTexture *background_texture;
   CoglPipeline *background_pipeline;
   CoglPipeline *background_shadow_pipeline;
-  CoglPipeline *color_pipeline;
 
   StThemeNodePaintState cached_state;
 
index f7932cd6f52a047404ba7abf787cc25ada5c0f38..19e90e822ce6e35d667ddd8798da21296d4cebb8 100644 (file)
@@ -244,10 +244,14 @@ st_theme_node_transition_get_paint_box (StThemeNodeTransition *transition,
 
 static gboolean
 setup_framebuffers (StThemeNodeTransition *transition,
+                    ClutterPaintNode      *node,
                     const ClutterActorBox *allocation,
                     float                  resource_scale)
 {
   StThemeNodeTransitionPrivate *priv = transition->priv;
+  g_autoptr (ClutterPaintNode) old_layer_node = NULL;
+  g_autoptr (ClutterPaintNode) new_layer_node = NULL;
+  CoglPipeline *noop_pipeline;
   CoglContext *ctx;
   guint width, height;
   GError *catch_error = NULL;
@@ -319,38 +323,45 @@ setup_framebuffers (StThemeNodeTransition *transition,
   cogl_pipeline_set_layer_texture (priv->material, 0, priv->new_texture);
   cogl_pipeline_set_layer_texture (priv->material, 1, priv->old_texture);
 
-  cogl_framebuffer_clear4f (priv->old_offscreen, COGL_BUFFER_BIT_COLOR,
-                            0, 0, 0, 0);
+  noop_pipeline = cogl_pipeline_new (ctx);
   cogl_framebuffer_orthographic (priv->old_offscreen,
                                  priv->offscreen_box.x1,
                                  priv->offscreen_box.y1,
                                  priv->offscreen_box.x2,
                                  priv->offscreen_box.y2, 0.0, 1.0);
 
+  old_layer_node = clutter_layer_node_new_to_framebuffer (priv->old_offscreen,
+                                                          noop_pipeline);
+  clutter_paint_node_add_child (node, old_layer_node);
+
   st_theme_node_paint (priv->old_theme_node, &priv->old_paint_state,
-                       priv->old_offscreen, allocation, 255, resource_scale);
+                       old_layer_node, allocation, 255, resource_scale);
 
-  cogl_framebuffer_clear4f (priv->new_offscreen, COGL_BUFFER_BIT_COLOR,
-                            0, 0, 0, 0);
+  new_layer_node = clutter_layer_node_new_to_framebuffer (priv->new_offscreen,
+                                                          noop_pipeline);
+  clutter_paint_node_add_child (node, new_layer_node);
   cogl_framebuffer_orthographic (priv->new_offscreen,
                                  priv->offscreen_box.x1,
                                  priv->offscreen_box.y1,
                                  priv->offscreen_box.x2,
                                  priv->offscreen_box.y2, 0.0, 1.0);
   st_theme_node_paint (priv->new_theme_node, &priv->new_paint_state,
-                       priv->new_offscreen, allocation, 255, resource_scale);
+                       new_layer_node, allocation, 255, resource_scale);
+
+  g_clear_object (&noop_pipeline);
 
   return TRUE;
 }
 
 void
 st_theme_node_transition_paint (StThemeNodeTransition *transition,
-                                CoglFramebuffer       *framebuffer,
+                                ClutterPaintNode      *node,
                                 ClutterActorBox       *allocation,
                                 guint8                 paint_opacity,
                                 float                  resource_scale)
 {
   StThemeNodeTransitionPrivate *priv = transition->priv;
+  g_autoptr (ClutterPaintNode) pipeline_node = NULL;
 
   CoglColor constant, pipeline_color;
   float tex_coords[] = {
@@ -370,7 +381,9 @@ st_theme_node_transition_paint (StThemeNodeTransition *transition,
 
       calculate_offscreen_box (transition, allocation);
       priv->needs_setup = clutter_actor_box_get_area (&priv->offscreen_box) == 0 ||
-                          !setup_framebuffers (transition, allocation,
+                          !setup_framebuffers (transition,
+                                               node,
+                                               allocation,
                                                resource_scale);
 
       if (priv->needs_setup) /* setting up framebuffers failed */
@@ -386,13 +399,12 @@ st_theme_node_transition_paint (StThemeNodeTransition *transition,
                            paint_opacity / 255.0, paint_opacity / 255.0);
   cogl_pipeline_set_color (priv->material, &pipeline_color);
 
-  cogl_framebuffer_draw_multitextured_rectangle (framebuffer,
-                                                 priv->material,
-                                                 priv->offscreen_box.x1,
-                                                 priv->offscreen_box.y1,
-                                                 priv->offscreen_box.x2,
-                                                 priv->offscreen_box.y2,
-                                                 tex_coords, 8);
+  pipeline_node = clutter_pipeline_node_new (priv->material);
+  clutter_paint_node_add_child (node, pipeline_node);
+  clutter_paint_node_add_multitexture_rectangle (pipeline_node,
+                                                 &priv->offscreen_box,
+                                                 tex_coords,
+                                                 8);
 }
 
 static void
index e7420e6d5395e54d89efffbfd05a15e7642c4901..e5eff47fbb7d7c65a771c7e9527f411a43c51fbb 100644 (file)
@@ -42,7 +42,7 @@ void  st_theme_node_transition_update   (StThemeNodeTransition *transition,
                                          StThemeNode           *new_node);
 
 void  st_theme_node_transition_paint    (StThemeNodeTransition *transition,
-                                         CoglFramebuffer       *framebuffer,
+                                         ClutterPaintNode      *node,
                                          ClutterActorBox       *allocation,
                                          guint8                 paint_opacity,
                                          float                  resource_scale);
index 1c7fb72fc24102f689fc0ed85f687059a66eec91..04f0966f108b484397bbb1d478cac3fd75181702 100644 (file)
@@ -132,7 +132,6 @@ st_theme_node_finalize (GObject *object)
   g_clear_object (&node->background_shadow_pipeline);
   g_clear_object (&node->border_slices_texture);
   g_clear_object (&node->border_slices_pipeline);
-  g_clear_object (&node->color_pipeline);
 
   G_OBJECT_CLASS (st_theme_node_parent_class)->finalize (object);
 }
index 63945d55908e6b419b7f57feea7e405939902db2..3227a8f11c9f5cbb9ce747f1f8f67b3906218f54 100644 (file)
@@ -342,7 +342,7 @@ gboolean st_theme_node_paint_equal    (StThemeNode *node,
  */
 void st_theme_node_paint (StThemeNode            *node,
                           StThemeNodePaintState  *state,
-                          CoglFramebuffer        *framebuffer,
+                          ClutterPaintNode       *root,
                           const ClutterActorBox  *box,
                           guint8                  paint_opacity,
                           float                   resource_scale);
index c87c0c2b107f2f6e72458a19963e843bc469063f..a8bd6668cf51693d7d63e093c77634997478fd28 100644 (file)
@@ -398,6 +398,31 @@ get_border_paint_offsets (StViewport *viewport,
 }
 
 
+static void
+st_viewport_paint_node (ClutterActor     *actor,
+                        ClutterPaintNode *node)
+{
+  StViewport *viewport = ST_VIEWPORT (actor);
+  int x, y;
+
+  get_border_paint_offsets (viewport, &x, &y);
+  if (x != 0 || y != 0)
+    {
+      g_autoptr (ClutterPaintNode) transform_node = NULL;
+      graphene_matrix_t transform;
+
+      graphene_matrix_init_translate (&transform,
+                                      &GRAPHENE_POINT3D_INIT (x, y, 0));
+
+      transform_node = clutter_transform_node_new (&transform);
+      clutter_paint_node_add_child (node, transform_node);
+
+      node = transform_node;
+    }
+
+  st_widget_paint_background (ST_WIDGET (actor), node);
+}
+
 static void
 st_viewport_paint (ClutterActor        *actor,
                    ClutterPaintContext *paint_context)
@@ -411,24 +436,14 @@ st_viewport_paint (ClutterActor        *actor,
   ClutterActor *child;
   CoglFramebuffer *fb = clutter_paint_context_get_framebuffer (paint_context);
 
-  get_border_paint_offsets (viewport, &x, &y);
-  if (x != 0 || y != 0)
-    {
-      cogl_framebuffer_push_matrix (fb);
-      cogl_framebuffer_translate (fb, x, y, 0);
-    }
-
-  st_widget_paint_background (ST_WIDGET (actor), paint_context);
-
-  if (x != 0 || y != 0)
-    cogl_framebuffer_pop_matrix (fb);
-
   if (clutter_actor_get_n_children (actor) == 0)
     return;
 
   clutter_actor_get_allocation_box (actor, &allocation_box);
   st_theme_node_get_content_box (theme_node, &allocation_box, &content_box);
 
+  get_border_paint_offsets (viewport, &x, &y);
+
   content_box.x1 += x;
   content_box.y1 += y;
   content_box.x2 += x;
@@ -564,6 +579,7 @@ st_viewport_class_init (StViewportClass *klass)
   actor_class->allocate = st_viewport_allocate;
   actor_class->apply_transform = st_viewport_apply_transform;
 
+  actor_class->paint_node = st_viewport_paint_node;
   actor_class->paint = st_viewport_paint;
   actor_class->get_paint_volume = st_viewport_get_paint_volume;
   actor_class->pick = st_viewport_pick;
index 807d8d0eb033ab3a332a4c06877de067b8f17432..8dba0ce98c278f7df5cf850d7a3a3bbb116caff0 100644 (file)
@@ -418,11 +418,10 @@ st_widget_allocate (ClutterActor          *actor,
  * painting children.
  */
 void
-st_widget_paint_background (StWidget            *widget,
-                            ClutterPaintContext *paint_context)
+st_widget_paint_background (StWidget         *widget,
+                            ClutterPaintNode *node)
 {
   StWidgetPrivate *priv = st_widget_get_instance_private (widget);
-  CoglFramebuffer *framebuffer;
   StThemeNode *theme_node;
   ClutterActorBox allocation;
   float resource_scale;
@@ -430,7 +429,6 @@ st_widget_paint_background (StWidget            *widget,
 
   resource_scale = clutter_actor_get_resource_scale (CLUTTER_ACTOR (widget));
 
-  framebuffer = clutter_paint_context_get_framebuffer (paint_context);
   theme_node = st_widget_get_theme_node (widget);
 
   clutter_actor_get_allocation_box (CLUTTER_ACTOR (widget), &allocation);
@@ -439,27 +437,24 @@ st_widget_paint_background (StWidget            *widget,
 
   if (priv->transition_animation)
     st_theme_node_transition_paint (priv->transition_animation,
-                                    framebuffer,
+                                    node,
                                     &allocation,
                                     opacity,
                                     resource_scale);
   else
     st_theme_node_paint (theme_node,
                          current_paint_state (widget),
-                         framebuffer,
+                         node,
                          &allocation,
                          opacity,
                          resource_scale);
 }
 
 static void
-st_widget_paint (ClutterActor        *actor,
-                 ClutterPaintContext *paint_context)
+st_widget_paint_node (ClutterActor     *actor,
+                      ClutterPaintNode *node)
 {
-  st_widget_paint_background (ST_WIDGET (actor), paint_context);
-
-  /* Chain up so we paint children. */
-  CLUTTER_ACTOR_CLASS (st_widget_parent_class)->paint (actor, paint_context);
+  st_widget_paint_background (ST_WIDGET (actor), node);
 }
 
 static void
@@ -892,7 +887,7 @@ st_widget_class_init (StWidgetClass *klass)
   actor_class->get_preferred_width = st_widget_get_preferred_width;
   actor_class->get_preferred_height = st_widget_get_preferred_height;
   actor_class->allocate = st_widget_allocate;
-  actor_class->paint = st_widget_paint;
+  actor_class->paint_node = st_widget_paint_node;
   actor_class->get_paint_volume = st_widget_get_paint_volume;
   actor_class->parent_set = st_widget_parent_set;
   actor_class->map = st_widget_map;
index f00c98733f67cfc7246d6a705022dfd57e07a66f..40866357d4916fbde75f0548b0597bb321e29cfc 100644 (file)
@@ -143,8 +143,8 @@ StThemeNode *         st_widget_get_theme_node            (StWidget        *widg
 StThemeNode *         st_widget_peek_theme_node           (StWidget        *widget);
 
 GList *               st_widget_get_focus_chain           (StWidget        *widget);
-void                  st_widget_paint_background          (StWidget            *widget,
-                                                           ClutterPaintContext *paint_context);
+void                  st_widget_paint_background          (StWidget         *widget,
+                                                           ClutterPaintNode *node);
 
 /* debug methods */
 char  *st_describe_actor       (ClutterActor *actor);